home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / ASTArrayDeclaration.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  7.0 KB  |  199 lines  |  [TEXT/KAHL]

  1. /* ASTArrayDeclaration.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "ASTArrayDeclaration.h"
  31. #include "TrashTracker.h"
  32. #include "Memory.h"
  33. #include "SymbolTableEntry.h"
  34. #include "ASTExpression.h"
  35. #include "PcodeObject.h"
  36.  
  37.  
  38. struct ASTArrayDeclRec
  39.     {
  40.         SymbolRec*                    SymbolTableEntry;
  41.         ASTExpressionRec*        SizeExpression;
  42.         long                                LineNumber;
  43.     };
  44.  
  45.  
  46. /* create a new array variable constructor node.  this should ONLY be used for */
  47. /* creating arrays.  variables that are initialized with an array that results from */
  48. /* an expression should use ASTVariableDeclaration.  */
  49. ASTArrayDeclRec*        NewArrayConstruction(struct SymbolRec* SymbolTableEntry,
  50.                                             struct ASTExpressionRec* SizeExpression,
  51.                                             struct TrashTrackRec* TrashTracker, long LineNumber)
  52.     {
  53.         ASTArrayDeclRec*    ArrayThing;
  54.  
  55.         CheckPtrExistence(SymbolTableEntry);
  56.         CheckPtrExistence(SizeExpression);
  57.         CheckPtrExistence(TrashTracker);
  58.         ERROR((GetSymbolVariableDataType(SymbolTableEntry) != eArrayOfBoolean)
  59.             && (GetSymbolVariableDataType(SymbolTableEntry) != eArrayOfInteger)
  60.             && (GetSymbolVariableDataType(SymbolTableEntry) != eArrayOfFloat)
  61.             && (GetSymbolVariableDataType(SymbolTableEntry) != eArrayOfDouble)
  62.             && (GetSymbolVariableDataType(SymbolTableEntry) != eArrayOfFixed),
  63.             PRERR(ForceAbort,"NewArrayConstruction:  variable type is NOT an array"));
  64.         ArrayThing = (ASTArrayDeclRec*)AllocTrackedBlock(sizeof(ASTArrayDeclRec),
  65.             TrashTracker);
  66.         if (ArrayThing == NIL)
  67.             {
  68.                 return NIL;
  69.             }
  70.         SetTag(ArrayThing,"ASTArrayDeclRec");
  71.  
  72.         ArrayThing->LineNumber = LineNumber;
  73.         ArrayThing->SymbolTableEntry = SymbolTableEntry;
  74.         ArrayThing->SizeExpression = SizeExpression;
  75.  
  76.         return ArrayThing;
  77.     }
  78.  
  79.  
  80. /* type check the array variable constructor node.  this returns eCompileNoError if */
  81. /* everything is ok, and the appropriate type in *ResultingDataType. */
  82. CompileErrors                TypeCheckArrayConstruction(DataTypes* ResultingDataType,
  83.                                             ASTArrayDeclRec* ArrayConstructor, long* ErrorLineNumber,
  84.                                             struct TrashTrackRec* TrashTracker)
  85.     {
  86.         DataTypes                    TheVariableType;
  87.         DataTypes                    SizeSpecifierType;
  88.         CompileErrors            Error;
  89.  
  90.         CheckPtrExistence(ArrayConstructor);
  91.         CheckPtrExistence(TrashTracker);
  92.  
  93.         if (WhatIsThisSymbol(ArrayConstructor->SymbolTableEntry) != eSymbolVariable)
  94.             {
  95.                 *ErrorLineNumber = ArrayConstructor->LineNumber;
  96.                 return eCompileExpectedVariable;
  97.             }
  98.  
  99.         TheVariableType = GetSymbolVariableDataType(ArrayConstructor->SymbolTableEntry);
  100.         switch (TheVariableType)
  101.             {
  102.                 default:
  103.                     EXECUTE(PRERR(ForceAbort,"TypeCheckArrayConstruction:  unknown data type"));
  104.                     break;
  105.                 case eBoolean:
  106.                 case eInteger:
  107.                 case eFloat:
  108.                 case eDouble:
  109.                 case eFixed:
  110.                     *ErrorLineNumber = ArrayConstructor->LineNumber;
  111.                     return eCompileExpectedArrayType;
  112.                 case eArrayOfBoolean:
  113.                 case eArrayOfInteger:
  114.                 case eArrayOfFloat:
  115.                 case eArrayOfDouble:
  116.                 case eArrayOfFixed:
  117.                     break;
  118.             }
  119.  
  120.         Error = TypeCheckExpression(&SizeSpecifierType,ArrayConstructor->SizeExpression,
  121.             ErrorLineNumber,TrashTracker);
  122.         if (Error != eCompileNoError)
  123.             {
  124.                 return Error;
  125.             }
  126.         if (SizeSpecifierType != eInteger)
  127.             {
  128.                 *ErrorLineNumber = ArrayConstructor->LineNumber;
  129.                 return eCompileArraySizeSpecMustBeInteger;
  130.             }
  131.  
  132.         *ResultingDataType = TheVariableType;
  133.         return eCompileNoError;
  134.     }
  135.  
  136.  
  137. /* generate code for array declaration.  returns True if successful, or False if */
  138. /* it fails. */
  139. MyBoolean                        CodeGenArrayConstruction(struct PcodeRec* FuncCode,
  140.                                             long* StackDepthParam, ASTArrayDeclRec* ArrayConstructor)
  141.     {
  142.         long                            StackDepth;
  143.         Pcodes                        OpcodeToGenerate;
  144.  
  145.         CheckPtrExistence(FuncCode);
  146.         CheckPtrExistence(ArrayConstructor);
  147.         StackDepth = *StackDepthParam;
  148.  
  149.         /* evaluate size expression, leaving result on stack */
  150.         if (!CodeGenExpression(FuncCode,&StackDepth,ArrayConstructor->SizeExpression))
  151.             {
  152.                 return False;
  153.             }
  154.         ERROR(StackDepth != *StackDepthParam + 1,PRERR(ForceAbort,
  155.             "CodeGenArrayConstruction:  CodeGenExpression made stack depth error"));
  156.  
  157.         /* construct array operation.  this pops size, but pushes new array reference */
  158.         switch (GetSymbolVariableDataType(ArrayConstructor->SymbolTableEntry))
  159.             {
  160.                 default:
  161.                     EXECUTE(PRERR(ForceAbort,"CodeGenArrayConstruction:  bad variable type"));
  162.                     break;
  163.                 case eArrayOfBoolean:
  164.                     OpcodeToGenerate = epMakeBooleanArray;
  165.                     break;
  166.                 case eArrayOfInteger:
  167.                     OpcodeToGenerate = epMakeIntegerArray;
  168.                     break;
  169.                 case eArrayOfFloat:
  170.                     OpcodeToGenerate = epMakeFloatArray;
  171.                     break;
  172.                 case eArrayOfDouble:
  173.                     OpcodeToGenerate = epMakeDoubleArray;
  174.                     break;
  175.                 case eArrayOfFixed:
  176.                     OpcodeToGenerate = epMakeFixedArray;
  177.                     break;
  178.             }
  179.         if (!AddPcodeInstruction(FuncCode,OpcodeToGenerate,NIL))
  180.             {
  181.                 return False;
  182.             }
  183.  
  184.         /* now make the symbol table entry remember where on the stack it is. */
  185.         SetSymbolVariableStackLocation(ArrayConstructor->SymbolTableEntry,StackDepth);
  186.  
  187.         /* duplicate the value for something to return */
  188.         if (!AddPcodeInstruction(FuncCode,epDuplicate,NIL))
  189.             {
  190.                 return False;
  191.             }
  192.         StackDepth += 1;
  193.         ERROR(StackDepth != *StackDepthParam + 2,PRERR(ForceAbort,
  194.             "CodeGenArrayConstruction:  stack depth error after duplicating value for return"));
  195.  
  196.         *StackDepthParam = StackDepth;
  197.         return True;
  198.     }
  199.